package com.easy.mongodb.starter.factory;


import com.easy.mongodb.common.enums.ProcessIndexStrategyEnum;
import com.easy.mongodb.common.utils.ExceptionUtils;
import com.easy.mongodb.starter.config.EasyMongoDBConfigProperties;
import com.easy.mongodb.starter.service.AutoProcessIndexService;
import com.mongodb.client.MongoClient;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * ProjectName: 自动托管索引策略工厂
 * Description: //TODO
 * Author: vapeshop
 * Date: 2022/6/20 15:17:08
 * UpdateUser: vapeshop
 * UpdateDate: 2022/6/20 15:17:08
 * UpdateRemark: The modified content
 * Version: 1.0
 * <p>
 * Copyright © 2022 vapeshop Technologies Inc. All Rights Reserved
 **/
@Component
@ConditionalOnClass(MongoClient.class)
@ConditionalOnProperty(prefix = "easy-mongodb", name = {"enable"}, havingValue = "true", matchIfMissing = true)
public class IndexStrategyFactory implements ApplicationContextAware, InitializingBean {
    /**
     * 预估初始策略工厂容量
     */
    private static final Integer DEFAULT_SIZE = 4;
    /**
     * 策略容器
     */
    private static final Map<Integer, AutoProcessIndexService> SERVICE_MAP = new HashMap<>(DEFAULT_SIZE);
    /**
     * 配置
     */
    @Autowired
    private EasyMongoDBConfigProperties mongoDBConfigProperties;
    /**
     * spring上下文
     */
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() {
        // 是否开启自动托管模式,默认开启
        if (!ProcessIndexStrategyEnum.MANUAL.equals(this.mongoDBConfigProperties.getGlobalConfig().getProcessIndexMode())) {
            // 将bean注册进工厂
            this.applicationContext.getBeansOfType(AutoProcessIndexService.class)
                    .values()
                    .forEach(v -> SERVICE_MAP.putIfAbsent(v.getStrategyType(), v));
        }
    }

    public AutoProcessIndexService getByStrategyType(Integer strategyType) {
        return Optional.ofNullable(SERVICE_MAP.get(strategyType))
                .orElseThrow(() -> ExceptionUtils.build("no such service strategyType:{}", strategyType));

    }
}
